import {Connection, SelectQueryBuilder} from "..";
import {EntitySchemaIndexOptions} from "./EntitySchemaIndexOptions";
import {EntitySchemaColumnOptions} from "./EntitySchemaColumnOptions";
import {EntitySchemaRelationOptions} from "./EntitySchemaRelationOptions";
import {OrderByCondition} from "../find-options/OrderByCondition";
import {TableType} from "../metadata/types/TableTypes";
import {EntitySchemaUniqueOptions} from "./EntitySchemaUniqueOptions";
import {EntitySchemaCheckOptions} from "./EntitySchemaCheckOptions";
import {EntitySchemaExclusionOptions} from "./EntitySchemaExclusionOptions";

/**
 * Interface for entity metadata mappings stored inside "schemas" instead of models decorated by decorators.
 */
export class EntitySchemaOptions<T> {

    /**
     * Name of the schema it extends.
     */
    extends?: string;

    /**
     * Target bind to this entity schema. Optional.
     */
    target?: Function;

    /**
     * Entity name.
     */
    name: string;

    /**
     * Table name.
     */
    tableName?: string;

    /**
     * Database name. Used in MySql and Sql Server.
     */
    database?: string;

    /**
     * Schema name. Used in Postgres and Sql Server.
     */
    schema?: string;

    /**
     * Table type.
     */
    type?: TableType;

    /**
     * Specifies a property name by which queries will perform ordering by default when fetching rows.
     */
    orderBy?: OrderByCondition;

    /**
     * Entity column's options.
     */
    columns: {
        [P in keyof T]?: EntitySchemaColumnOptions;
    };

    /**
     * Entity relation's options.
     */
    relations?: {
        [P in keyof T]?: EntitySchemaRelationOptions;
    };

    /**
    * Entity indices options.
    */
    indices?: EntitySchemaIndexOptions[];

    /**
    * Entity uniques options.
    */
    uniques?: EntitySchemaUniqueOptions[];

    /**
    * Entity check options.
    */
    checks?: EntitySchemaCheckOptions[];

    /**
    * Entity exclusion options.
    */
    exclusions?: EntitySchemaExclusionOptions[];

    /**
     * Indicates if schema synchronization is enabled or disabled for this entity.
     * If it will be set to false then schema sync will and migrations ignore this entity.
     * By default schema synchronization is enabled for all entities.
     */
    synchronize?: boolean;

    /**
     * View expression.
     */
    expression?: string|((connection: Connection) => SelectQueryBuilder<any>);

}
